#pragma once

/* instruction table */
struct t_opcode base_inst[57] = {
    {NULL, "ADC", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0x61, 0},    //BJP removed ZP_IND mode
    {NULL, "AND", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0x21, 0},    //BJP removed ZP_IND mode
    {NULL, "ASL", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x02, 0},
    {NULL, "BCC", class2, 0, 0x90, 0},
    {NULL, "BCS", class2, 0, 0xB0, 0},
    {NULL, "BEQ", class2, 0, 0xF0, 0},
    {NULL, "BIT", class4, IMM|ZP|ZP_X|ABS|ABS_X, 0x00, 2},
    {NULL, "BMI", class2, 0, 0x30, 0},
    {NULL, "BNE", class2, 0, 0xD0, 0},
    {NULL, "BPL", class2, 0, 0x10, 0},
    {NULL, "BRK", class1, 0, 0x00, 0},
    {NULL, "BVC", class2, 0, 0x50, 0},
    {NULL, "BVS", class2, 0, 0x70, 0},
    {NULL, "CLC", class1, 0, 0x18, 0},
    {NULL, "CLD", class1, 0, 0xD8, 0},
    {NULL, "CLI", class1, 0, 0x58, 0},
    {NULL, "CLV", class1, 0, 0xB8, 0},
    {NULL, "CMP", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0xC1, 0},    //BJP removed ZP_IND mode
    {NULL, "CPX", class4, IMM|ZP|ABS, 0xE0, 1},
    {NULL, "CPY", class4, IMM|ZP|ABS, 0xC0, 1},
    {NULL, "DEC", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x00, 3},
    {NULL, "DEX", class1, 0, 0xCA, 0},
    {NULL, "DEY", class1, 0, 0x88, 0},
    {NULL, "EOR", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0x41, 0},    //BJP removed ZP_IND mode
    {NULL, "INC", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x00, 4},
    {NULL, "INX", class1, 0, 0xE8, 0},
    {NULL, "INY", class1, 0, 0xC8, 0},
    {NULL, "JMP", class4, ABS|ABS_IND|ABS_IND_X, 0x40, 0},
    {NULL, "JSR", class4, ABS, 0x14, 0},
    {NULL, "LDA", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0xA1, 0},    //BJP removed ZP_IND mode
    {NULL, "LDX", class4, IMM|ZP|ZP_Y|ABS|ABS_Y, 0xA2, 1},
    {NULL, "LDY", class4, IMM|ZP|ZP_X|ABS|ABS_X, 0xA0, 1},
    {NULL, "LSR", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x42, 0},
    {NULL, "NOP", class1, 0, 0xEA, 0},
    {NULL, "ORA", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0x01, 0},    //BJP removed ZP_IND mode
    {NULL, "PHA", class1, 0, 0x48, 0},
    {NULL, "PHP", class1, 0, 0x08, 0},
    {NULL, "PLA", class1, 0, 0x68, 0},
    {NULL, "PLP", class1, 0, 0x28, 0},
    {NULL, "ROL", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x22, 0},
    {NULL, "ROR", class4, ACC|ZP|ZP_X|ABS|ABS_X, 0x62, 0},
    {NULL, "RTI", class1, 0, 0x40, 0},
    {NULL, "RTS", class1, 0, 0x60, 0},
    {NULL, "SBC", class4, IMM|ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0xE1, 0},    //BJP removed ZP_IND mode
    {NULL, "SEC", class1, 0, 0x38, 0},
    {NULL, "SED", class1, 0, 0xF8, 0},
    {NULL, "SEI", class1, 0, 0x78, 0},
    {NULL, "STA", class4, ZP|ZP_X|ZP_IND_X|ZP_IND_Y|ABS|ABS_X|ABS_Y, 0x81, 0},    //BJP removed ZP_IND mode
    {NULL, "STX", class4, ZP|ZP_Y|ABS, 0x82, 0},
    {NULL, "STY", class4, ZP|ZP_X|ABS, 0x80, 0},
    {NULL, "TAX", class1, 0, 0xAA, 0},
    {NULL, "TAY", class1, 0, 0xA8, 0},
    {NULL, "TSX", class1, 0, 0xBA, 0},
    {NULL, "TXA", class1, 0, 0x8A, 0},
    {NULL, "TXS", class1, 0, 0x9A, 0},
    {NULL, "TYA", class1, 0, 0x98, 0},
    {NULL, NULL, NULL, 0, 0, 0}
};

/* pseudo instruction table */
struct t_opcode base_pseudo[] = {
    {NULL,  "=",            do_equ,         PSEUDO,     P_EQU,     0},
    {NULL,  "BANK",         do_bank,        PSEUDO,     P_BANK,    0},
    {NULL,  "BANK8",        do_bank8,       PSEUDO,     P_BANK,    0},
    {NULL,  "BANK16",       do_bank16,      PSEUDO,     P_BANK,    0},
    {NULL,  "BANK32",       do_bank32,      PSEUDO,     P_BANK,    0},
    {NULL,  "BSS",          do_section,     PSEUDO,     P_BSS,     S_BSS},
    {NULL,  "BYTE",         do_db,          PSEUDO,     P_DB,      0},
    {NULL,  "CALL",         do_call,        PSEUDO,     P_CALL,    0},
    {NULL,  "CODE",         do_section,     PSEUDO,     P_CODE,    S_CODE},
    {NULL,  "DATA",         do_section,     PSEUDO,     P_DATA,    S_DATA},
    {NULL,  "DB",           do_db,          PSEUDO,     P_DB,      0},
    {NULL,  "DW",           do_dw,          PSEUDO,     P_DW,      0},
    {NULL,  "RDW",          do_rdw,         PSEUDO,     P_RDW,     0},
    {NULL,  "DS",           do_ds,          PSEUDO,     P_DS,      0},
    {NULL,  "ELSE",         do_else,        PSEUDO,     P_ELSE,    0},
    {NULL,  "ENDIF",        do_endif,       PSEUDO,     P_ENDIF,   0},
    {NULL,  "ENDM",         do_endm,        PSEUDO,     P_ENDM,    0},
    {NULL,  "ENDP",         do_endp,        PSEUDO,     P_ENDP,    P_PROC},
    {NULL,  "ENDPROCGROUP", do_endp,        PSEUDO,     P_ENDPG,   P_PGROUP},
    {NULL,  "EQU",          do_equ,         PSEUDO,     P_EQU,     0},
    {NULL,  "FAIL",         do_fail,        PSEUDO,     P_FAIL,    0},
    {NULL,  "FUNC",         do_func,        PSEUDO,     P_FUNC,    0},
    {NULL,  "IF",           do_if,          PSEUDO,     P_IF,      0},
    {NULL,  "IFDEF",        do_ifdef,       PSEUDO,     P_IFDEF,   1},
    {NULL,  "IFNDEF",       do_ifdef,       PSEUDO,     P_IFNDEF,  0},
    {NULL,  "INCBIN",       do_incbin,      PSEUDO,     P_INCBIN,  0},
    {NULL,  "INCLUDE",      do_include,     PSEUDO,     P_INCLUDE, 0},
    {NULL,  "INCCHR",       do_incchr,      PSEUDO,     P_INCCHR,  0xEA},
    {NULL,  "LIST",         do_list,        PSEUDO,     P_LIST,    0},
    {NULL,  "MAC",          do_macro,       PSEUDO,     P_MACRO,   0},
    {NULL,  "MACRO",        do_macro,       PSEUDO,     P_MACRO,   0},
    {NULL,  "MLIST",        do_mlist,       PSEUDO,     P_MLIST,   0},
    {NULL,  "NOLIST",       do_nolist,      PSEUDO,     P_NOLIST,  0},
    {NULL,  "NOMLIST",      do_nomlist,     PSEUDO,     P_NOMLIST, 0},
    {NULL,  "OPT",          do_opt,         PSEUDO,     P_OPT,     0},
    {NULL,  "ORG",          do_org,         PSEUDO,     P_ORG,     0},
    {NULL,  "BASE",         do_base,        PSEUDO,     P_ORG,     0},
    {NULL,  "PAGE",         do_page,        PSEUDO,     P_PAGE,    0},
    {NULL,  "PROC",         do_proc,        PSEUDO,     P_PROC,    P_PROC},
    {NULL,  "PROCGROUP",    do_proc,        PSEUDO,     P_PGROUP,  P_PGROUP},
    {NULL,  "RSSET",        do_rsset,       PSEUDO,     P_RSSET,   0},
    {NULL,  "RS",           do_rs,          PSEUDO,     P_RS,      0},
    {NULL,  "WORD",         do_dw,          PSEUDO,     P_DW,      0},
    {NULL,  "RWORD",        do_rdw,         PSEUDO,     P_RDW,     0},
    {NULL,  "ZP",           do_section,     PSEUDO,     P_ZP,      S_ZP},
    {NULL,  "STR",          do_str,         PSEUDO,     P_STR,     0},
    {NULL,  "USTR",         do_str_upper,   PSEUDO,     P_STR,     0},
    {NULL,  "LSTR",         do_str_lower,   PSEUDO,     P_STR,     0},
    {NULL,  "HEX",          do_hex,         PSEUDO,     P_HEX,     0},
    {NULL,  "FILL",         do_fill,        PSEUDO,     P_STR,     0},

    {NULL, ".BANK",         do_bank,        PSEUDO,     P_BANK,    0},
    {NULL, ".BANK8",        do_bank8,       PSEUDO,     P_BANK,    0},
    {NULL, ".BANK16",       do_bank16,      PSEUDO,     P_BANK,    0},
    {NULL, ".BANK32",       do_bank32,      PSEUDO,     P_BANK,    0},
    {NULL, ".BSS",          do_section,     PSEUDO,     P_BSS,     S_BSS},
    {NULL, ".BYTE",         do_db,          PSEUDO,     P_DB,      0},
    {NULL, ".CODE",         do_section,     PSEUDO,     P_CODE,    S_CODE},
    {NULL, ".DATA",         do_section,     PSEUDO,     P_DATA,    S_DATA},
    {NULL, ".DB",           do_db,          PSEUDO,     P_DB,      0},
    {NULL, ".DW",           do_dw,          PSEUDO,     P_DW,      0},
    {NULL, ".RDW",          do_rdw,         PSEUDO,     P_RDW,     0},
    {NULL, ".DS",           do_ds,          PSEUDO,     P_DS,      0},
    {NULL, ".ELSE",         do_else,        PSEUDO,     P_ELSE,    0},
    {NULL, ".ENDIF",        do_endif,       PSEUDO,     P_ENDIF,   0},
    {NULL, ".ENDM",         do_endm,        PSEUDO,     P_ENDM,    0},
    {NULL, ".ENDP",         do_endp,        PSEUDO,     P_ENDP,    P_PROC},
    {NULL, ".ENDPROCGROUP", do_endp,        PSEUDO,     P_ENDPG,   P_PGROUP},
    {NULL, ".EQU",          do_equ,         PSEUDO,     P_EQU,     0},
    {NULL, ".FAIL",         do_fail,        PSEUDO,     P_FAIL,    0},
    {NULL, ".FUNC",         do_func,        PSEUDO,     P_FUNC,    0},
    {NULL, ".IF",           do_if,          PSEUDO,     P_IF,      0},
    {NULL, ".IFDEF",        do_ifdef,       PSEUDO,     P_IFDEF,   1},
    {NULL, ".IFNDEF",       do_ifdef,       PSEUDO,     P_IFNDEF,  0},
    {NULL, ".INCBIN",       do_incbin,      PSEUDO,     P_INCBIN,  0},
    {NULL, ".INCLUDE",      do_include,     PSEUDO,     P_INCLUDE, 0},
    {NULL, ".INCCHR",       do_incchr,      PSEUDO,     P_INCCHR,  0xEA},
    {NULL, ".LIST",         do_list,        PSEUDO,     P_LIST,    0},
    {NULL, ".MAC",          do_macro,       PSEUDO,     P_MACRO,   0},
    {NULL, ".MACRO",        do_macro,       PSEUDO,     P_MACRO,   0},
    {NULL, ".MLIST",        do_mlist,       PSEUDO,     P_MLIST,   0},
    {NULL, ".NOLIST",       do_nolist,      PSEUDO,     P_NOLIST,  0},
    {NULL, ".NOMLIST",      do_nomlist,     PSEUDO,     P_NOMLIST, 0},
    {NULL, ".OPT",          do_opt,         PSEUDO,     P_OPT,     0},
    {NULL, ".ORG",          do_org,         PSEUDO,     P_ORG,     0},
    {NULL, ".BASE",         do_base,        PSEUDO,     P_ORG,     0},
    {NULL, ".PAGE",         do_page,        PSEUDO,     P_PAGE,    0},
    {NULL, ".PROC",         do_proc,        PSEUDO,     P_PROC,    P_PROC},
    {NULL, ".PROCGROUP",    do_proc,        PSEUDO,     P_PGROUP,  P_PGROUP},
    {NULL, ".RSSET",        do_rsset,       PSEUDO,     P_RSSET,   0},
    {NULL, ".RS",           do_rs,          PSEUDO,     P_RS,      0},
    {NULL, ".WORD",         do_dw,          PSEUDO,     P_DW,      0},
    {NULL, ".RWORD",        do_rdw,         PSEUDO,     P_RDW,     0},
    {NULL, ".ZP",           do_section,     PSEUDO,     P_ZP,      S_ZP},
    {NULL, ".STR",          do_str,         PSEUDO,     P_STR,     0},
    {NULL, ".USTR",         do_str_upper,   PSEUDO,     P_STR,     0},
    {NULL, ".LSTR",         do_str_lower,   PSEUDO,     P_STR,     0},
    {NULL, ".HEX",          do_hex,         PSEUDO,     P_HEX,     0},
    {NULL, ".FILL",         do_fill,        PSEUDO,     P_STR,     0},
    {NULL, NULL, NULL,      0, 0, 0}
};

